/*
 * Logger.cpp
 *
 *  Created on: 15.03.2013
 *      Author: mag
 */

#include <errno.h>
#include <stdarg.h>

#include "Logger.h"
#include "HWClock.h"

DECLARE_LOG_SUPPORT(BACKEND)

void Logger::set_logfile(const char *filename) {
	if (logfile && logfile!=stderr)
		fclose(logfile);
	if (filename && *filename) {

		logfile=fopen(filename, "a");
		if (!logfile) {
			logfile=stderr;
		}
	}
}

void Logger::set_dumpfile(const char *filename) {
	if (dumpfile)
		fclose(dumpfile);
	if (filename && !filename) {
		dumpfile=fopen(filename, "a");
		if (!dumpfile) {
			error("error on opening dumpfile '%s', errno=%d", filename, errno);
		}
	} else {
		dumpfile=0;
	}
}

void Logger::shutdown() {
	if (logfile && logfile!=stderr)
		fclose(logfile);
	if (dumpfile)
		fclose(dumpfile);
	dumpfile=0;
	logfile=stderr;
}


current_mutex Logger::log_mutex;
current_mutex Logger::dump_mutex;

int Logger::log_mask=Logger::VERBOSE;

size_t Logger::dump_size=0;
FILE *Logger::dumpfile=0;
FILE *Logger::logfile=stderr;

void Logger::vlog(int module, int lvl, const char *fmt, va_list ap) {
//	if ((lvl & log_mask) != 0) { // check log verbosity
		synchronized(log_mutex) {
			HWClock now=HWClock::now();
			char buffer[HWClock::TS_BUFFER_SIZE];
			fprintf(logfile,"[%s]-[%3x]: ", now.timestamp(buffer,HWClock::TS_BUFFER_SIZE), lvl);
			vfprintf(logfile, fmt, ap);
			fprintf(logfile, "\n");
		}
//	}
}

void Logger::log(int module, int lvl, const char *fmt, ...) {
	va_list va;
	va_start(va, fmt);
	Logger::vlog(module,lvl,fmt,va);
}

void Logger::dump(size_t sz, void *data) {
	if (dumpfile) {
		synchronized(dump_mutex) {
			// dump record: <timestamp> <size> <data..>
			HWClock now=HWClock::now();
			fwrite(&now, sizeof(now), 1, dumpfile);
			fwrite(&sz, sizeof(size_t), 1, dumpfile);
			fwrite(data, 1, sz, dumpfile);

			dump_size+=sz;
			if (dump_size>DUMP_THRESHHOLD) {
				// flush every 256kB
				fflush(dumpfile);
				dump_size=0;
			}
		}
	}
}

